<?php

namespace Base\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\MvcEvent;
use Zend\Session\Container;
use Zend\View\Model\ViewModel;
use Library\Acl;

class BaseController extends AbstractActionController {

    protected $authservice;

    protected $storage;

    protected $table;

    protected $userInfo;

    protected $viewData;

    protected $session;

    protected $message;

    protected $log;

    protected $language;

    private function _init() {
        $this->viewData = new ViewModel();
        $this->session = new Container('reunion_session');
        $this->message = $this->flashMessenger();
        $this->log = $this->getServiceLocator()->get('LogHandle');
        $this->language = $this->getServiceLocator()->get('translator');
    }

    public function setEventManager(EventManagerInterface $events) {
        parent::setEventManager($events);
        $this->_init();
    }

    protected function attachDefaultListeners() {
        parent::attachDefaultListeners();
        $events = $this->getEventManager();
        $events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 100);
        $events->attach(MvcEvent::EVENT_RENDER, array($this, 'postRender'), -100);
    }

    public function postRender() {
        $this->message->clearMessages();
    }

    public function preDispatch() {
        if (!$this->getAuthService()->hasIdentity()){
            return $this->layout('user/login');
        }
        
        $isAllow = $this->getUserPermission();
        $allConfig = $this->getServiceLocator()->get('config');
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'NA');
        $controllerName = $this->getEvent()->getRouteMatch()->getParam('controller', 'NA');
        $controllers = explode('\\', $controllerName);
//        if (isset($allConfig['unlimit'])) {
//            $unlimit = $allConfig['unlimit'];
//            if (isset($unlimit[$controllers[2]]) && in_array($actionName, $unlimit[$controllers[2]])) {
//                $isAllow = 1;
//            }
//        }

        $lang = $this->getEvent()->getRouteMatch()->getParam('lang', 'NA');
        $allLanguage = $this->getLanguages();
        if (in_array($lang, $allLanguage)) {
            $this->userInfo['user_lang'] = $lang;
            $this->session->userLang = $lang;
        } elseif ($this->session->userLang) {
            $this->userInfo['user_lang'] = $this->session->userLang;
        }

        $pathname = array('namespace'=>$controllers[0], 'controller'=>$controllers[2], 'action'=>$actionName);
        $this->layout()->username = $this->userInfo['user_name'];
        $this->layout()->pathname = $pathname;
        $this->layout()->usertype = $this->userInfo['user_type'];
        $this->layout()->page = array();
        $this->layout()->languages = $allLanguage;
        $this->layout()->isAllow = $isAllow;
        $this->layout()->userlang = $this->userInfo['user_lang'];
        $this->viewData->userInfo = $this->userInfo;

        $this->language->setLocale($this->userInfo['user_lang']);
        $this->log->info(sprintf($this->language->translate('log_route_to'), $this->userInfo['user_name'], $controllers[2], $actionName));

        if ($this->message->hasMessages()) {
            foreach ($this->message->getMessages() as $message) {
                $this->viewData->$message = $message;
            }
        }

        if (!$isAllow) {
            $this->log->info(sprintf($this->language->translate('log_user_permission'), $this->userInfo['user_name'], $controllers[2], $actionName));
            $this->viewData->setTemplate('error/403');
            return $this->viewData;
        }
    }

    protected function getAuthService() {
        if (!$this->authservice) {
            $this->authservice = $this->getServiceLocator()->get('AuthService');
        }
        return $this->authservice;
    }

    protected function getSessionStorage() {
        if (!$this->storage) {
            $this->storage = $this->getServiceLocator()->get('User\Model\UserStorage');
        }
        return $this->storage;
    }

    protected function getTable($serviceDbTableName, $dbTableName = '', $dbName = '') {
        if (!isset($this->table[$serviceDbTableName]) || !$this->table[$serviceDbTableName]) {
            $this->table[$serviceDbTableName] = $this->getServiceLocator()->get($serviceDbTableName);
        }
        $this->table[$serviceDbTableName]->init($dbTableName, $dbName);
        return $this->table[$serviceDbTableName];
    }

    protected function getUserPermission() {
        $this->userInfo = $this->getAuthService()->getIdentity();
        if ($this->userInfo['user_name'] == $this->session->superadmin) {
            return 1;
        }
        if (empty($this->userInfo)) {
            $aclArray = array(
                'acl' => array(
                    'roles' => array(
                        'guest' => null
                    ),
                    'resources' => array(
                        'deny' => array(
                            'all' => 'guest',
                        ),
                        'allow' => array(
                            'User\Controller\User\login' => 'guest',
                        ),
                    )
                )
            );
            $this->userInfo['acl'] = new Acl($aclArray);
            $this->userInfo['user_name'] = 'guest';
        }
        $actionName = $this->getEvent()->getRouteMatch()->getParam('action', 'NA');
        $controllerName = $this->getEvent()->getRouteMatch()->getParam('controller', 'NA');
        $resourceName = $controllerName.'\\'.$actionName;
        $isAllow = 0;
        if($this->userInfo['acl']->hasResource($resourceName) && $this->userInfo['acl']->isAllowed($this->userInfo['user_name'], $resourceName)) {
            $isAllow = 1;
        }
        return $isAllow;
    }

    protected function getLanguages() {
        $srcDir = __DIR__. '/../../../language/';
        $langInfo = array();
        $languageFileArray = glob($srcDir.'*.php');
        foreach ($languageFileArray as $languageFile) {
            if (preg_match_all("/.*\/(.*?)\.php/is", $languageFile, $matches)) {
                $langInfo[] = $matches[1][0];
            }
        }
        return $langInfo;
    }
}
